<script setup lang="ts">
import { useGuessPullupLoad } from '@/composables'
import {
  deleteMemberOrderAPI,
  getMemberOrderByIdAPI,
  getMemberOrderCancelByIdAPI,
  getMemberOrderConsignmentByIdAPI,
  getMemberOrderLogisticsByIdAPI,
  getPayMockAPI,
  getPayWxPayMiniPayAPI,
  putMemberOrderReceiptByIdAPI,
} from '@/services'
import { OrderState, orderStateList } from '@/services/constants'
import type { LogisticItem, OrderResult } from '@/types'
import type { UniPopupInstance } from '@uni-helper/uni-ui-types'
import { onLoad, onReady } from '@dcloudio/uni-app'
import { ref } from 'vue'
import PageSkeleton from './components/PageSkeleton.vue'

// 是否为开发环境
const isDev = import.meta.env.DEV
// 获取屏幕边界到安全区域距离
const { safeAreaInsets } = uni.getSystemInfoSync()
// 获取页面栈
const pages = getCurrentPages()

// #ifdef MP-WEIXIN
// uni-app不支持animate类型，基于微信小程序的Page实例类型扩展uni-app的Page实例类型
type PageInstance = Page.PageInstance & WechatMiniprogram.Page.InstanceMethods<any>
// 获取当前页面实例
const pageInstance = pages.at(-1) as PageInstance
/* 导航栏实现滚动驱动动画 */
onReady(() => {
  // 导航栏背景色动画效果
  pageInstance.animate(
    '.navbar', // 选择器
    [{ backgroundColor: 'transparent' }, { backgroundColor: '#f8f8f8' }], // 关键帧信息
    1000, // 动画持续时长
    {
      scrollSource: '#scroller', // scroll-view的选择器
      startScrollOffset: 0, // 开始滚动偏移量
      endScrollOffset: 50, // 停止滚动偏移量
      timeRange: 1000, // 时间长度
    },
  )
  // 导航栏标题动画效果
  pageInstance.animate('.navbar .title', [{ color: 'transparent' }, { color: '#000' }], 1000, {
    scrollSource: '#scroller',
    startScrollOffset: 0,
    endScrollOffset: 50,
    timeRange: 1000,
  })
  // 导航栏返回按钮动画效果
  pageInstance.animate('.navbar .back', [{ color: '#fff' }, { color: '#000' }], 1000, {
    scrollSource: '#scroller',
    startScrollOffset: 0,
    endScrollOffset: 50,
    timeRange: 1000,
  })
})
// #endif

interface Props {
  id: string
}
const query = defineProps<Props>()
const order = ref<OrderResult>()
const logisticList = ref<LogisticItem[]>([])
// 获取订单物流信息
const getMemberOrderLogisticsByIdData = async () => {
  const res = await getMemberOrderLogisticsByIdAPI(query.id)
  logisticList.value = res.result.list
}
// 获取订单详情
const getMemberOrderByIdData = async () => {
  const res = await getMemberOrderByIdAPI(query.id)
  order.value = res.result
  if (
    [OrderState.DaiShouHuo, OrderState.DaiPingJia, OrderState.YiWanCheng].includes(
      order.value.orderState,
    )
  ) {
    // 仅在订单状态为待收货、待评价、已完成时，可获取订单的物流信息
    getMemberOrderLogisticsByIdData()
  }
}
onLoad(() => {
  getMemberOrderByIdData()
})
const onTimeup = () => {
  // 倒计时结束，主动更新订单状态为已取消
  order.value!.orderState = OrderState.YiQuXiao
}

// 取消订单的原因列表
const reasonList = ref([
  '商品无货',
  '不想要了',
  '商品信息填错了',
  '地址信息填写错误',
  '商品降价',
  '其它',
])
const popupRef = ref<UniPopupInstance | null>(null)
const reason = ref('')
/* 取消订单 */
const onOrderCancel = async () => {
  const res = await getMemberOrderCancelByIdAPI(query.id, { cancelReason: reason.value })
  // 更新订单信息
  order.value = res.result
  popupRef.value?.close?.()
  uni.showToast({ icon: 'success', title: '订单取消成功' })
}

/* 支付订单 */
const onOrderPay = async () => {
  if (isDev) {
    // 开发环境：模拟支付，修改订单状态为已支付
    await getPayMockAPI({ orderId: query.id })
  } else {
    // #ifdef MP-WEIXIN
    // 微信生产环境：获取支付参数 + 发起微信支付
    const res = await getPayWxPayMiniPayAPI({ orderId: query.id })
    await wx.requestPayment(res.result)
    // #endif

    // #ifdef H5 || APP-PLUS
    // H5端和App端未开通支付，一律使用模拟支付体验
    await getPayMockAPI({ orderId: query.id })
    // #endif
  }
  // 关闭当前页，再跳转支付结果页
  uni.redirectTo({ url: `/pagesOrder/payment/payment?id=${query.id}` })
}

/* 模拟发货 */
const onOrderSend = async () => {
  // isDev判断的作用：仅在开发环境下使用，打包到生产环境会剔除以下代码（tree shaking树摇优化）
  if (isDev) {
    await getMemberOrderConsignmentByIdAPI(query.id)
    uni.showToast({ icon: 'success', title: '模拟发货成功' })
    // 主动更新订单状态为待收货
    order.value!.orderState = OrderState.DaiShouHuo
  }
}

/* 确认收货 */
const onOrderConfirm = () => {
  uni.showModal({
    title: '提示',
    content: '为保障您的权益，请收到货并确认无误后，再确认收货',
    confirmColor: '#27BA9B',
    success: async (res) => {
      if (res.confirm) {
        const { result } = await putMemberOrderReceiptByIdAPI(query.id)
        uni.showToast({ icon: 'success', title: '确认收货成功' })
        // 主动更新订单状态
        order.value = result
      }
    },
  })
}

/* 删除订单 */
const onOrderDelete = () => {
  uni.showModal({
    title: '提示',
    content: '是否确定删除该订单？',
    confirmColor: '#27BA9B',
    success: async (res) => {
      if (res.confirm) {
        // 仅在订单状态为待评价、已完成、已取消时，可删除订单
        await deleteMemberOrderAPI({ ids: [query.id] })
        uni.showToast({ icon: 'success', title: '订单删除成功' })
        setTimeout(() => {
          // 关闭当前页，再跳转订单列表页
          uni.redirectTo({ url: '/pagesOrder/list/list' })
        }, 400)
      }
    },
  })
}

// 复制订单编号
const onOrderIdCopy = (id: string) => {
  // 设置系统剪贴板的内容
  uni.setClipboardData({ data: id })
}

// 上拉加载猜你喜欢数据
const { guessRef, onScrolltolower } = useGuessPullupLoad()
</script>

<template>
  <!-- 自定义导航栏: 默认透明不可见, scroll-view滚动到50px时展示 -->
  <view class="navbar" :style="{ paddingTop: safeAreaInsets?.top + 'px' }">
    <view class="wrap">
      <navigator
        v-if="pages.length > 1"
        open-type="navigateBack"
        class="back icon-left"
      ></navigator>
      <navigator v-else open-type="switchTab" url="/pages/index/index" class="back icon-home">
      </navigator>
      <view class="title">订单详情</view>
    </view>
  </view>
  <scroll-view
    id="scroller"
    class="viewport"
    scroll-y
    enable-back-to-top
    @scrolltolower="onScrolltolower"
  >
    <template v-if="order">
      <!-- 订单状态 -->
      <view class="overview" :style="{ paddingTop: safeAreaInsets!.top + 20 + 'px' }">
        <!-- 待付款状态：展示去支付按钮和倒计时 -->
        <template v-if="order.orderState === OrderState.DaiFuKuan">
          <view class="status icon-clock">等待付款</view>
          <view class="tips">
            <text class="money">应付金额：¥ {{ order.payMoney }}</text>
            <text class="time">支付剩余</text>
            <!-- 倒计时 -->
            <uni-countdown
              :second="order.countdown"
              :show-day="false"
              :show-colon="false"
              color="#fff"
              splitor-color="#fff"
              @timeup="onTimeup"
            />
          </view>
          <view class="button" @tap="onOrderPay">去支付</view>
        </template>
        <!-- 其他订单状态：展示再次购买按钮 -->
        <template v-else>
          <!-- 订单状态文字 -->
          <view class="status">{{ orderStateList[order.orderState].text }}</view>
          <view class="button-group">
            <navigator
              class="button"
              :url="`/pagesOrder/create/create?orderId=${query.id}`"
              hover-class="none"
            >
              再次购买
            </navigator>
            <!-- 待发货状态：模拟发货，开发期间使用，用于修改订单状态为待收货 -->
            <view
              v-if="isDev && order.orderState === OrderState.DaiFaHuo"
              class="button"
              @tap="onOrderSend"
            >
              模拟发货
            </view>
            <!-- 待收货状态：展示确认收货按钮 -->
            <view
              v-if="order.orderState === OrderState.DaiShouHuo"
              class="button"
              @tap="onOrderConfirm"
              >确认收货</view
            >
          </view>
        </template>
      </view>
      <!-- 配送状态 -->
      <view class="shipment">
        <!-- 订单物流信息 -->
        <view class="item" v-for="item in logisticList" :key="item.id">
          <view class="message">{{ item.text }} </view>
          <view class="date">{{ item.time }}</view>
        </view>
        <!-- 用户收货地址 -->
        <view class="locate">
          <view class="user">{{ order.receiverContact }} {{ order.receiverMobile }}</view>
          <view class="address">{{ order.receiverAddress }}</view>
        </view>
      </view>
      <!-- 商品信息 -->
      <view class="goods">
        <view class="item">
          <navigator
            v-for="item in order.skus"
            :key="item.id"
            class="navigator"
            hover-class="none"
            :url="`/pages/goods/goods?id=${item.spuId}`"
          >
            <image class="cover" :src="item.image" />
            <view class="meta">
              <view class="name ellipsis-1">{{ item.name }}</view>
              <view class="attrsText ellipsis-2">{{ item.attrsText }}</view>
              <view class="price">
                <view class="actual">
                  <text class="symbol">¥</text>
                  <text>{{ item.curPrice }}</text>
                </view>
              </view>
              <view class="quantity">x{{ item.quantity }}</view>
            </view>
          </navigator>
          <!-- 待评价状态：展示按钮 -->
          <view class="action" v-if="order.orderState === OrderState.DaiPingJia">
            <view class="button primary">申请售后</view>
            <navigator url="" class="button">去评价</navigator>
          </view>
        </view>
        <!-- 合计 -->
        <view class="total">
          <view class="row">
            <view class="text">商品总价：</view>
            <view class="symbol">{{ order.totalMoney.toFixed(2) }}</view>
          </view>
          <view class="row">
            <view class="text">运费：</view>
            <view class="symbol">{{ order.postFee.toFixed(2) }}</view>
          </view>
          <view class="row">
            <view class="text">应付金额：</view>
            <view class="symbol primary">{{ order.payMoney.toFixed(2) }}</view>
          </view>
        </view>
      </view>
      <!-- 订单信息 -->
      <view class="detail">
        <view class="title">订单信息</view>
        <view class="row">
          <view class="item">
            订单编号：{{ query.id }} <text class="copy" @tap="onOrderIdCopy(query.id)">复制</text>
          </view>
          <view class="item">下单时间：{{ order.createTime }}</view>
        </view>
      </view>
      <!-- 猜你喜欢 -->
      <XtxGuess ref="guessRef" />
      <!-- 底部占位空盒子 -->
      <view class="toolbar-height" :style="{ paddingBottom: safeAreaInsets?.bottom + 'px' }"></view>
      <!-- 底部操作栏 -->
      <view class="toolbar" :style="{ paddingBottom: safeAreaInsets?.bottom + 'px' }">
        <!-- 待付款状态：展示支付按钮 -->
        <template v-if="order.orderState === OrderState.DaiFuKuan">
          <view class="button primary" @tap="onOrderPay">去支付</view>
          <view class="button" @tap="popupRef?.open?.()">取消订单</view>
        </template>
        <!-- 其他订单状态：按需展示按钮 -->
        <template v-else>
          <navigator
            class="button secondary"
            hover-class="none"
            :url="`/pagesOrder/create/create?orderId=${query.id}`"
          >
            再次购买
          </navigator>
          <!-- 待收货状态：展示确认收货 -->
          <view
            class="button primary"
            v-if="order.orderState === OrderState.DaiShouHuo"
            @tap="onOrderConfirm"
            >确认收货</view
          >
          <!-- 待评价状态：展示去评价 -->
          <view class="button" v-if="order.orderState === OrderState.DaiPingJia">去评价</view>
          <!-- 待评价/已完成/已取消状态：展示删除订单 -->
          <view
            class="button delete"
            v-if="
              [OrderState.DaiPingJia, OrderState.YiWanCheng, OrderState.YiQuXiao].includes(
                order.orderState,
              )
            "
            @tap="onOrderDelete"
            >删除订单</view
          >
        </template>
      </view>
    </template>
    <template v-else>
      <!-- 骨架屏 -->
      <PageSkeleton />
    </template>
  </scroll-view>
  <!-- 取消订单弹窗 -->
  <uni-popup ref="popupRef" type="bottom" background-color="#fff">
    <view class="popup-root">
      <view class="title">订单取消</view>
      <view class="description">
        <view class="tips">请选择取消订单的原因：</view>
        <view class="cell" v-for="item in reasonList" :key="item" @tap="reason = item">
          <text class="text">{{ item }}</text>
          <text :class="['icon', { checked: item === reason }]"></text>
        </view>
      </view>
      <view class="footer">
        <view class="button" @tap="popupRef?.close?.()">取消</view>
        <view class="button primary" @tap="onOrderCancel">确认</view>
      </view>
    </view>
  </uni-popup>
</template>

<style lang="scss">
@import './styles/detail.scss';
</style>
